import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

public class EditorCreator {
	public static void createItemRulesComboCell(final Table table,
			final List itemRules) {
		final TableEditor editor = new TableEditor(table);
		editor.horizontalAlignment = SWT.LEFT;
		editor.grabHorizontal = true;
		table.addMouseListener(new MouseListener() {

			public void mouseUp(MouseEvent arg0) {
			}

			public void mouseDown(MouseEvent arg0) {
				Control oldEditor = editor.getEditor();
				if (oldEditor != null) {
					oldEditor.dispose();
				}
				Point pt = new Point(arg0.x, arg0.y);

				int index = table.getSelectionIndex();
				if (index < 0) {
					return;
				}
				final TableItem item = table.getSelection()[0];
				if (item == null) {
					return;
				}
				int count = -1;
				for (int i = 0, n = table.getColumnCount(); i < n; i++) {
					Rectangle rect = item.getBounds(i);
					if (rect.contains(pt)) {
						count = i;
						break;
					}
				}
				if (count >= table.getColumnCount() || count < 0) {
					return;
				}
				final int column = count;
				editor.minimumWidth = table.getColumn(column).getWidth();
				if (table.getColumn(column).getText().equals(Const.ITEM_RULES)) {
					final Combo newEditor = new Combo(table, SWT.NONE);
					newEditor.setText(item.getText(column));
					newEditor.setVisibleItemCount(10);
					Iterator ite = itemRules.iterator();
					while (ite.hasNext()) {
						(newEditor).add(ite.next().toString());
					}
					newEditor.addFocusListener(new FocusListener() {
						public void focusLost(FocusEvent me) {
							Combo combo = (Combo) editor.getEditor();
							if (combo.getText() == "") {
								editor.getItem().setText(column,
										combo.getText());
								editor.getItem().setText(column + 1,
										combo.getText());
								return;
							}
							for (int i = 0; i < combo.getItems().length; i++) {
								if (combo.getItem(i).indexOf(combo.getText()) == 0) {
									editor.getItem().setText(column,
											combo.getItem(i));
									editor.getItem().setText(
											column + 1,
											Utils.getItemRules(itemRules,
													combo.getItem(i))
													.getLabel());
									break;
								}
							}
							ItemRules tmp = Utils.getItemRules(itemRules,
									newEditor.getText());
							if (newEditor.getText().length() <= 0
									|| tmp == null) {
								tmp = new ItemRules(item);
							}
							Validator.checkItemRulesForText(table, item,
									new NodeModel(item), tmp, false);
							Validator.checkItemRulesForLabel(table, item,
									new NodeModel(item), tmp, false);
							newEditor.dispose();
						}

						public void focusGained(FocusEvent me) {
						}
					});
					newEditor.addKeyListener(new KeyListener() {
						public void keyReleased(KeyEvent arg0) {
						}

						public void keyPressed(KeyEvent ke) {
						}
					});
					newEditor.addListener(SWT.DefaultSelection, new Listener() {
						public void handleEvent(Event arg0) {
							table.forceFocus();
							table.deselectAll();
						}
					});
					newEditor.setFocus();
					editor.setEditor(newEditor, item, column);
				}
			}

			public void mouseDoubleClick(MouseEvent arg0) {
			}
		});
	}

	public static void createTextEditor(final Table table,
			final List itemRules, final String ColumnName) {
		final TableEditor editor = new TableEditor(table);
		editor.horizontalAlignment = SWT.LEFT;
		editor.grabHorizontal = true;
		table.addMouseListener(new MouseListener() {
			public void mouseUp(MouseEvent arg0) {
			}

			public void mouseDown(MouseEvent arg0) {
				Control oldEditor = editor.getEditor();
				if (oldEditor != null) {
					oldEditor.dispose();
				}
				Point pt = new Point(arg0.x, arg0.y);

				int index = table.getSelectionIndex();
				if (index < 0) {
					return;
				}
				final TableItem item = table.getSelection()[0];
				if (item == null) {
					return;
				}
				int count = -1;
				for (int i = 0, n = table.getColumnCount(); i < n; i++) {
					Rectangle rect = item.getBounds(i);
					if (rect.contains(pt)) {
						count = i;
						break;
					}
				}
				if (count >= table.getColumnCount() || count < 0) {
					return;
				}
				final int column = count;
				editor.minimumWidth = table.getColumn(column).getWidth();
				if (table.getColumn(column).getText().equals(ColumnName)
						|| table.getColumn(column).getText().equals(Const.ALL)) {
					final Text newEditor = new Text(table, SWT.NONE);
					newEditor.setText(item.getText(column));
					newEditor.selectAll();
					newEditor.addModifyListener(new ModifyListener() {
						public void modifyText(ModifyEvent me) {
							Text combo = (Text) editor.getEditor();
							editor.getItem().setText(column, combo.getText());
						}
					});
					newEditor.addFocusListener(new FocusListener() {
						public void focusLost(FocusEvent me) {
							if (table.getColumn(column).getText().equals(
									Const.SHOW_LENGTH)) {
								Validator.checkWitdh(editor, column);
								newEditor.dispose();
							}
							if (table.getColumn(column).getText().equals(
									Const.ITEM_RULES_LABEL)) {
								ItemRules tmp = new ItemRules();
								tmp.setLabel(newEditor.getText());
								Validator.checkItemRulesForLabel(table, item,
										new NodeModel(item), tmp, false);
							}
							newEditor.dispose();
						}

						public void focusGained(FocusEvent me) {
						}
					});
					newEditor.addKeyListener(new KeyListener() {
						public void keyReleased(KeyEvent arg0) {
						}

						public void keyPressed(KeyEvent ke) {
							if (ke.keyCode == SWT.ARROW_DOWN
									|| ke.keyCode == SWT.ARROW_UP) {
								table.forceFocus();
								table.deselectAll();
							}
						}
					});
					newEditor.addListener(SWT.DefaultSelection, new Listener() {
						public void handleEvent(Event arg0) {
							table.forceFocus();
							table.deselectAll();
						}
					});
					newEditor.setFocus();
					editor.setEditor(newEditor, item, column);
				}

			}

			public void mouseDoubleClick(MouseEvent arg0) {
			}
		});
	}
}
